package org.sbbs.base.tenant.tenancy;

import lombok.extern.slf4j.Slf4j;
import org.sbbs.base.tenant.entity.TenantDS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;

@Slf4j
@Component
@Qualifier("routDS")
public class SbbsTenantRoutingDatasource extends AbstractRoutingDataSource {
    
    private final SbbsTenantIdResolver sbbsTenantIdResolver;
    
    public SbbsTenantRoutingDatasource(@Autowired DataSourceProperties masterDsProp, SbbsTenantIdResolver sbbsTenantIdResolver) {
        log.debug("default db properties is: {}", masterDsProp.toString());
        this.sbbsTenantIdResolver = sbbsTenantIdResolver;
        setDefaultTargetDataSource(this.CreateDS(masterDsProp));
        HashMap<Object, Object> targetDataSources = new HashMap<>();
        setTargetDataSources(targetDataSources);
    }
    
    public void initTenantDs(List<TenantDS> tdl) {
        log.debug("init tenant ds list is:{}", tdl);
        HashMap<Object, Object> targetDataSources = new HashMap<>();
        for (TenantDS t : tdl) {
            targetDataSources.put(t.getTenant().getCode(), createDatabase(t.getUrl(), t.getUserName(), t.getPassWord(), t.getDriverClass()));
        }
        log.debug("inited ds is:{}",targetDataSources.toString());
        setTargetDataSources(targetDataSources);
        
    }
    
    @Override
    protected String determineCurrentLookupKey() {
        String currentTenantId = sbbsTenantIdResolver.resolveCurrentTenantIdentifier();
        log.debug("determine current lookup key is:{}",currentTenantId);
        return currentTenantId;
    }
    
    private DataSource createDatabase(String databaseUrl, String username, String password, String driver) {
        DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
        dataSourceBuilder.driverClassName(driver);
        dataSourceBuilder.url(databaseUrl);
        dataSourceBuilder.username(username);
        dataSourceBuilder.password(password);
        return dataSourceBuilder.build();
    }
    
    private DataSource CreateDS(DataSourceProperties masterDsProp) {
        return masterDsProp.initializeDataSourceBuilder().build();
    }
}
